package top.wshape1.shiziapi.project.controller;

import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.wshape1.shiziapi.common.constant.AuthConstant;
import top.wshape1.shiziapi.common.domain.CommonUser;
import top.wshape1.shiziapi.common.domain.to.SummaryDocReqTo;
import top.wshape1.shiziapi.common.domain.vo.PageVo;
import top.wshape1.shiziapi.common.utils.Base64Util;
import top.wshape1.shiziapi.common.utils.R;
import top.wshape1.shiziapi.project.common.annotation.EditHistoryLog;
import top.wshape1.shiziapi.project.common.constant.EditConstant;
import top.wshape1.shiziapi.project.domain.vo.*;
import top.wshape1.shiziapi.project.service.DocumentService;

import java.util.List;

/**
 * @author Wshape1
 * @version 1.0
 * @description
 * @since 2023-10-22
 */

@RestController
@RequestMapping("/doc")
public class DocumentController {

    @Resource
    private DocumentService documentService;

    /**
     * 获取文档列表
     *
     * @param projectId
     * @param userBase64
     * @return
     */
    @GetMapping("/list")
    public R<List<DocVo>> docList(@RequestParam("projectId") Long projectId,
                                  @RequestHeader(value = AuthConstant.HEADER_PAYLOAD_NAME, required = false) String userBase64) {

        Long userId = null;
        if (userBase64 != null)
            userId = Base64Util.decodeAndParse(userBase64, CommonUser.class).getId();

        List<DocVo> docList = documentService.docList(projectId, userId);

        return R.ok(docList);
    }

    /**
     * 创建文档
     *
     * @param createDocVo
     * @param userBase64
     * @return
     */
    @EditHistoryLog(type = EditConstant.EDIT_TYPE_CREATE_DOC, projectIdParamName = "createDocVo.projectId", docTypeParamName = "createDocVo.type")
    @PostMapping("/create")
    public R<Long> createDoc(@RequestBody @Validated CreateDocVo createDocVo,
                             @RequestHeader(AuthConstant.HEADER_PAYLOAD_NAME) String userBase64) {

        CommonUser commonUser = Base64Util.decodeAndParse(userBase64, CommonUser.class);

        Long id = documentService.create(createDocVo, commonUser.getId());

        return R.ok(id);
    }

    /**
     * 重命名文档
     *
     * @param renameDocVo
     * @param userBase64
     * @return
     */
    @EditHistoryLog(type = EditConstant.EDIT_TYPE_RENAME_DOC, projectIdParamName = "renameDocVo.projectId",
            docIdParamName = "renameDocVo.id", docTypeParamName = "renameDocVo.type", docNameParamName = "renameDocVo.name")
    @PostMapping("/rename")
    public R<Void> renameDoc(@RequestBody @Validated RenameDocVo renameDocVo,
                             @RequestHeader(AuthConstant.HEADER_PAYLOAD_NAME) String userBase64) {

        CommonUser commonUser = Base64Util.decodeAndParse(userBase64, CommonUser.class);

        documentService.rename(renameDocVo, commonUser.getId());

        return R.ok();
    }

    /**
     * 删除文档
     *
     * @param deleteDocVo
     * @param userBase64
     * @return
     */
    @EditHistoryLog(type = EditConstant.EDIT_TYPE_DELETE_DOC, projectIdParamName = "deleteDocVo.projectId",
            docIdParamName = "deleteDocVo.id", docTypeParamName = "deleteDocVo.type")
    @PostMapping("/delete")
    public R<Void> deleteDoc(@RequestBody @Validated DeleteDocVo deleteDocVo,
                             @RequestHeader(AuthConstant.HEADER_PAYLOAD_NAME) String userBase64) {

        CommonUser commonUser = Base64Util.decodeAndParse(userBase64, CommonUser.class);

        documentService.delete(deleteDocVo, commonUser.getId());

        return R.ok();
    }

    /**
     * 重新设置文档排序
     *
     * @param reorderDocVo
     * @return
     */
    @PostMapping("/reorder")
    public R<Void> reorderDoc(@RequestBody @Validated ReorderDocVo reorderDocVo) {

        documentService.reorder(reorderDocVo);

        return R.ok();
    }

    /**
     * 重新设置文档排序(批量更新，不包括parentFolderId)
     *
     * @param reorderDocVos
     * @return
     */
    @PostMapping("/reorder_batch")
    public R<Void> reorderDocBatch(@RequestBody @Validated List<ReorderDocVo> reorderDocVos) {

        documentService.reorderBatch(reorderDocVos);

        return R.ok();
    }

    @PostMapping("/upload/image")
    public R<UploadImageRespVO> uploadImage(@RequestParam("image") MultipartFile image) {

        UploadImageRespVO uploadUrl = documentService.uploadImage(image);

        return R.ok().putData(uploadUrl);
    }

    /**
     * 获取文档历史版本列表
     *
     * @param docVersionQueryVo 查询参数
     * @return 版本列表
     */
    @PostMapping("/version/list")
    public R<PageVo> listDocVersion(@RequestBody DocVersionQueryVo docVersionQueryVo,
                                    @RequestParam(value = "page", required = false, defaultValue = "1") Long page,
                                    @RequestParam(value = "limit", required = false, defaultValue = "6") Long limit) {

        PageVo docVersionVoPageVo = documentService.listPageDocVersion(
                docVersionQueryVo,
                page,
                limit
        );

        return R.ok(docVersionVoPageVo);
    }

    /**
     * 获取文档历史版本详情
     *
     * @param docVersionQueryVo 查询参数
     * @return 版本详情
     */
    @PostMapping("/version/query")
    public R<DocVersionVo> queryDocVersion(@RequestBody DocVersionQueryVo docVersionQueryVo) {
        DocVersionVo docVersionVo = documentService.queryDocVersion(
                docVersionQueryVo.getProjectId(),
                docVersionQueryVo.getDocId(),
                docVersionQueryVo.getVersion(),
                docVersionQueryVo.getDocType()
        );
        return R.ok(docVersionVo);
    }

    /**
     * 保存文档版本
     */
    @EditHistoryLog(type = EditConstant.EDIT_TYPE_SAVE_VERSION, projectIdParamName = "docVersionSaveVo.projectId",
            docIdParamName = "docVersionSaveVo.docId", docTypeParamName = "docVersionSaveVo.docType", versionParamName = "docVersionSaveVo.version")
    @PostMapping("/version/save")
    public R<Long> saveDocVersion(@RequestBody DocVersionSaveVo docVersionSaveVo) {
        Long id = documentService.saveDocVersion(docVersionSaveVo);
        return R.ok(id);
    }

    /**
     * 获取文档版本详情（包含内容） 用于查询
     *
     * @param docVersionQueryVo
     * @return
     */
    @PostMapping("/version/get")
    public R<DocVersionVo> getDocVersion(@RequestBody DocVersionQueryVo docVersionQueryVo) {
        DocVersionVo docVersionVo = documentService.getDocVersionWithContent(
                docVersionQueryVo.getProjectId(),
                docVersionQueryVo.getDocId(),
                docVersionQueryVo.getVersion(),
                docVersionQueryVo.getDocType()
        );
        return R.ok(docVersionVo);
    }

    @EditHistoryLog(type = EditConstant.EDIT_TYPE_DELETE_VERSION, projectIdParamName = "data.projectId",
            versionIdParamName = "data.id")
    @PostMapping("/version/delete")
    public R<Boolean> deleteDocVersion(@RequestBody TwoIdVo data) {
        boolean b = documentService.deleteDocVersion(data.getId(), data.getProjectId());
        return R.ok(b);
    }

    /**
     * 文档开始编辑，用于保证只有一个人编辑文档
     *
     * @param startEditVo
     * @return
     */
    @PostMapping("/startEdit")
    public R<String> startEdit(@RequestBody StartEditVo startEditVo) {

        Long editorId = documentService.startEdit(startEditVo);

        if (editorId == null) {
            return R.error();
        } else {
            return R.ok().putData(String.valueOf(editorId));
        }
    }

    @PostMapping("/stopEdit")
    public R<Void> stopEdit(@RequestBody StartEditVo startEditVo) {

        documentService.stopEdit(startEditVo);

        return R.ok();
    }

    @PostMapping("/isSummaryGenerating")
    public R<DocSummaryGeneratingVo> isSummaryGenerating(@RequestBody StartEditVo vo) {

        DocSummaryGeneratingVo b = documentService.isSummaryGenerating(vo.getProjectId(), vo.getDocId(), vo.getDocType());

        return R.ok(b);
    }

    @PostMapping("/getSummary")
    public R<DocSummaryVo> getSummary(@RequestBody StartEditVo vo) {

        DocSummaryVo summary = documentService.getSummaryDocument(vo.getProjectId(), vo.getDocId(), vo.getDocType());

        return R.ok(summary);
    }

    @PostMapping("/aiSummary")
    public R<Void> aiSummary(@RequestBody StartEditVo vo) {

        documentService.summaryDocument(vo.getProjectId(), vo.getDocId(), vo.getDocType());

        return R.ok();
    }

}
